package cn.zsc.netdisk.service;

import cn.zsc.netdisk.common.Paths;
import cn.zsc.netdisk.common.UserInfo;
import cn.zsc.netdisk.mapper.UserMapper;
import cn.zsc.netdisk.pojo.User;
import cn.zsc.netdisk.service.cache.UserCacheService;
import cn.zsc.netdisk.util.EncodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;

/**
 * @author ccying
 * @date 2021/2/4
 */
@Service
@Slf4j
public class UserService {
    private final UserMapper mapper;
    private final FileService fileService;
    private final UserCacheService cacheService;

    public UserService(UserCacheService cacheService, UserMapper mapper, FileService fileService) {
        this.cacheService = cacheService;
        this.mapper = mapper;
        this.fileService = fileService;
    }

    /**
     * 缓存所有用户
     * */
    @PostConstruct
    public void init() {
        log.info("缓存所有用户");
        User[] users = this.mapper.findUser();
        for (User user : users) {
            this.cacheService.update(user);
        }
    }

    /**
     * 获取当前登录用户
     * @return 当前登录用户信息
     * */
    public User authentication() {
        log.info("获取当前登录用户");
        String uid = UserInfo.getPrincipal();
        return this.findUserByUid(uid);
    }

    /**
     * 根据用户账号查找用户
     * @param uid 用户账号
     * @return 用户信息
     * */
    public User findUserByUid(String uid) {
        log.info("根据用户账号查找用户");
        return this.cacheService.findUserByUid(uid);
    }

    /**
     * 根据用户账号绑定手机号码查找用户
     * @param mobile 手机号码
     * @return 用户信息
     * */
    public User findUserByMobile(String mobile) {
        log.info("根据用户账号绑定手机号码查找用户");
        return this.cacheService.findUserByMobile(mobile);
    }

    /**
     * 添加用户信息
     * @param user 用户
     * */
    public void addUser(User user) throws Exception {
        log.info("添加用户信息");
        this.mapper.addUser(user);
    }

    /**
     * 添加用户信息
     * @param uid 用户账号
     * @param mobileNumber 用户手机号码
     * @param password 用户密码
     * */
    public void addUser(String uid, String mobileNumber, String password) throws Exception {
        User user = new User();
        user.setUid(uid);
        user.setMobile(mobileNumber);
        user.setPassword(EncodeUtil.encode(password));
        this.cacheService.update(user);
        this.addUser(user);
    }

    /**
     * 修改用户头像
     * @param file 头像文件
     * */
    public void updateAvatar(MultipartFile file) throws Exception {
        log.info("修改用户头像");
        String uid = UserInfo.getPrincipal();
        //头像存储路径
        String path = Paths.AVATAR_ROOT_PATH + uid + ".png";
        //保存头像文件
        this.fileService.saveFile(path, file);
    }

    /**
     * 根据用户账号绑定手机号码更改用户密码
     * @param mobile 手机号码
     * @param password 新密码
     * @throws Exception
     * @return 修改后用户信息
     * */
    public User updatePasswordByMobile(String mobile, String password) throws Exception {
        log.info("根据用户账号绑定手机号码更改用户密码");
        User user = this.findUserByMobile(mobile);
        if (user != null) {
            //如果用户为空，说明该手机号码未绑定用户账号
            user.setPassword(EncodeUtil.encode(password));
            this.mapper.updatePasswordByMobile(mobile, password);
            this.cacheService.update(user);
            return user;
        } else {
            return null;
        }
    }

    /**
     * 修改绑定用户手机号码
     * @param mobileNumber 手机号码
     * @return 修改后用户信息
     * */
    public User updateMobile(String mobileNumber) throws Exception {
        log.info("修改绑定用户手机号码");
        User user = this.authentication();
        user.setMobile(mobileNumber);
        this.cacheService.update(user);
        this.mapper.updateMobileByUid(user.getUid(), user.getMobile());
        return user;
    }

    /**
     * 修改绑定用户电子邮箱
     * @param email 电子邮箱
     * @return 修改后用户信息
     * */
    public User updateEmail(String email) throws Exception {
        log.info("修改绑定用户电子邮箱");
        //获取当前登录用户
        User user = this.authentication();
        user.setEmail(email);
        //更新用户信息数据库
        this.mapper.updateEmailByUid(user.getUid(), user.getEmail());
        //回写用户信息缓存库
        this.cacheService.update(user);
        return user;
    }
}
